package chap_02_CAS.step_02_Atomic;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * @Description 对象的属性修改原子类
 * @Author shihan
 * @Date 2022/10/30 11:37
 * @Version 1.0
 */
public class Atomic_02_IntegerFieldUpdater {

    // 银行卡号
    private String cardNo = "123212345221";
    // 生日
    private String birthday = "1997-02-08";
    // 存款
    private double money = 0;

    /**
     * 原始的 synchronized 方法不是不可以，而是锁粒度有点大，锁的是 this 对象
     *
     * @param m
     */
    public synchronized void handleMoney(double m) {
        money += m;
    }

    // 银行卡积分
    //【必须要用 public volatile 来修饰属性】
    public volatile int point = 0;

    //【抽象类的静态方法实例化 FieldUpdater 对象，并指明类、属性】
    private AtomicIntegerFieldUpdater<Atomic_02_IntegerFieldUpdater> fieldUpdater =
            AtomicIntegerFieldUpdater.newUpdater(
                    Atomic_02_IntegerFieldUpdater.class,
                    "point"
            );

    public void handlePoint(Atomic_02_IntegerFieldUpdater obj, int delta) {
        //【借助 FieldUpdater 的原子操作，更新属性字段的值，锁粒度更细】
        fieldUpdater.addAndGet(obj, delta);
    }

    public static void main(String[] args) {
        //originWithSynchronized();
        originWithFieldUpdater();
    }

    private static void originWithFieldUpdater() {
        Atomic_02_IntegerFieldUpdater fieldUpdater = new Atomic_02_IntegerFieldUpdater();
        // 一共有十个线程
        CountDownLatch countDownLatch = new CountDownLatch(10);

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    // 每个线程内循环一百次
                    for (int j = 0; j < 100; j++) {
                        // 每次加10元
                        fieldUpdater.handlePoint(fieldUpdater, 10);
                    }
                } finally {
                    // 用 try-catch-finally 包裹是确保异常情况也能 countDown
                    countDownLatch.countDown();
                }
            }, String.valueOf(i)).start();
        }

        try {
            // 阻塞
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 打印结果
        System.out.println(fieldUpdater.point);
    }

    private static void originWithSynchronized() {
        Atomic_02_IntegerFieldUpdater fieldUpdater = new Atomic_02_IntegerFieldUpdater();
        // 一共有十个线程
        CountDownLatch countDownLatch = new CountDownLatch(10);

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    // 每个线程内循环一百次
                    for (int j = 0; j < 100; j++) {
                        // 每次加10元
                        fieldUpdater.handleMoney(10);
                    }
                } finally {
                    // 用 try-catch-finally 包裹是确保异常情况也能 countDown
                    countDownLatch.countDown();
                }
            }, String.valueOf(i)).start();
        }

        try {
            // 阻塞
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 打印结果
        System.out.println(fieldUpdater.money);
    }

}
